<?php

//UMA new
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use Cache;

class CustomerHistory extends Model
{
    protected $fillable = [
        'temporary_member_id',
        'input_info',
        'usage_term_accepted',
        'score',
        'min_interests',
        'max_interests',
        'min_total_payment',
        'max_total_payment',
        'nikkei_score',
        'random_score',
        'ip',
        'user_agent',
        'operation_system',
        'company_id',
        'working_years',
        'score_rank_id',
        'customer_id',
    ];

    protected $casts = [
        'input_info' => 'array',
    ];

    protected $attributes = [
        'usage_term_accepted' => 1,
    ];
        
    /**
     * 自动设置工作年限的值
     * 設定 working_years 値
     * @return void
     */
    public static function boot()
    {
        parent::boot();
        static::creating(function ($model) {
            $years = now()->diffInYears(Carbon::parse($model->input_info['employment_start_date']), false);
            $model->working_years = $years >= 0 ? 0 : abs($years);
        });
    }

    /**
     * 一个用户有一个咨询信息
     * 1人のユーザーに1つの連絡先があります
     * @return hasOne
     */

    public function contact()
    {
        return $this->hasOne(ContactInfo::class, 'customer_history_id')->latest();
    }

    /**
     * 客户属于一个公司
     * 顧客は会社に属しています
     *
     * @return belongsTo
     */

    public function company()
    {
        return $this->belongsTo(Company::class, 'company_id')->withDefault();
    }

    public function score_rank() {
        return $this->belongsTo(ScoreRank::class, 'score_rank_id')->withDefault();
    }


    public function customer() {
        return $this->belongsTo(Customer::class, 'customer_id')->withDefault();
    }

    /**
     * 获取 kintone 需要的用户输入的数据内容
     * データを取得する
     * @return array
     */
    public function getCustomerInputInfoAttribute()
    {
        $datas = $this->getSelectedOptions();
        foreach($datas as $v) {
            $res[$v->identifier] = ['value' => $v->selected_option->value ?? $v->selected_option->option_name];
        }
        return $res;
    }

    public function getMailData() {
        $datas = $this->getSelectedOptions(true);
        $res = [];
        foreach ($datas as $key => $group) {
            foreach ($group->items as $item) {
                $res[$group->identifier][$item->identifier] = $item->selected_option->value??$item->selected_option->option_name;
            }
        }
        return $res;
    }

    //collection of InputOptions
    public function getSelectedOptions($grouped = false)
    {
        $groups = InputGroup::with('items.options')->get();

        $info = $this->input_info;
        foreach ($groups as $group) {
            foreach ($group->items as $k => $item) {
                if(isset($info[$item->identifier])) {
                    $value = $info[$item->identifier];
                    $item->selected_option = $item->getOptionByValue($value);
                    unset($item->options);
                }
                else {
                    unset($group->items[$k]);
                }
            }
        }

        return $grouped ? $groups : $groups->pluck('items')->flatten();
    }



    /**
     * getAcceptedTextAttribute
     * 契約の説明に同意する
     * @return string
     */
    public function getAcceptedTextAttribute()
    {
        return $this->usage_term_accepted ? '済' : '未';
    }

    /**
     * getKintoneData
     * 获取 kintone 需要的 customer_histories 表的全部的信息
     * 取得する kinetone すべての情報
     * @return array
     */
    public function getKintoneData()
    {
        $excludes = [
            'input_info',
            'updated_at',
            'created_at',
        ];
        $datas = $this->toArray();

        foreach ($datas as $k => $v) {
            $datas[$k] = ['value' => $this->getCalculatedValue($k)];
        }

        $datas['company_name']['value'] = $this->company->company_name ?? '';
        return array_merge($this->customer_input_info, $datas);
    }

    public function getCalculatedValue($k) {
        $method = 'get_'.$k.'_text_value';
        if(method_exists($this, $method)) {
            return $this->$method();
        }
        return $this->$k;
    }
    
    
    /**
     * getMessage
     *
     * @return String
     */
    public function getMessage()
    {
        return ScoreRank::level($this->score)->value('message');
    }
    
    /**
     * getAgeAttribute
     *
     * @return String
     */
    public function getAgeAttribute()
    {
        return now()->year - $this->input_info['year_of_birth'];
    }
    
    
    /**
     * get_score_value
     *
     * @return String
     */
    public function get_score_text_value()
    {
        $rank = ScoreRank::level($this->score)->first()->score_rank;
        return $this->score.' ('.$rank.')';
    }
    
    /**
     * get_company_id_value
     *
     * @return String
     */
    // public function get_company_id_value()
    // {
    //     return $this->company_id. ' ('.$this->company->company_name.')';
    // }
    
    /**
     * get_usage_term_accepted_value
     *
     * @return string
     */
    public function get_usage_term_accepted_value()
    {
        return $this->accepted_text;
    }


    public function calculateScore() {

        $score = 1000;
        $datas = $this->getSelectedOptions();
        foreach ($datas->pluck('selected_option') as $option) {
            $score *= $option->rate;
        }
        return intval($score);
    }

    public function getNikkeiRate() {
        return Nikkei::latest('date')->first()->nikkei_score_rate->rate ?? 1;
    }   

    public function getNikkeiScore() {
        return intval($this->score * ($this->getNikkeiRate() -1));
    }

    public function getRandomScore() {
        $config_info = config('const.config');
        return random_int($config_info['extra_score_start'], $config_info['extra_score_end']);
    }

    public function getTotalScoreAttribute() {
        return $this->score + $this->getNikkeiScore() + $this->getRandomScore();
    }

    public function getScoreRankId() {
        return ScoreRank::rank($this->score)->value('id');
    }

    public function getMonthlyTotalPaymentAttribute() {
        $info = $this->input_info;
        return floatval($info['monthly_autoloan_repayment']) + floatval($info['monthly_cashloan_repayment']) + floatval($info['monthly_otherloan_repayment']);
    }

    public function getYearlyBalanceAttribute() {
        return $this->input_info['yearly_income'] - $this->monthly_total_payment * 12 ;
    }

    public function getMonthlyRepaymentAttribute() {
        $yearly_balance = $this->yearly_balance;
        $rate = $yearly_balance < 400 ? 0.3 : 0.35; 
        return $yearly_balance / 12 * $rate; 
    }

    public function getPeriodAttribute() {
        return min(80 - $this->age, 35);
    }


    public function getTotalLoanAmount() {
        if($this->yearly_balance <= 0) {
            return ['min' => 0, 'max' => 0];
        }

        $monthly_repayment = $this->monthly_repayment;
        $period = $this->period;
        $config_info = config('const.config');
        $interests = $config_info['interests'] / 100;
        //计算可能贷款额度
        //可能なローン金額を計算する
        $a = $monthly_repayment * 10000 * (pow((1 + $interests / 12), ($period * 12)) - 1);
        $b = $interests / 12 * (pow((1 + $interests / 12), $period * 12));
        $debt = round($a / $b) / 10000;
        return [
            'min' => round($debt * (1 + $config_info['rate_min'] / 100)),
            'max' => round($debt * (1 + $config_info['rate_max'] / 100))
        ];
        
    }

    // public function getInputInfoContentAttribute() {
    //     $datas = $this->getInputTextValue(false);
    //     return implode(' ',$datas);
    //     //return view('admin.inputinfo', ['datas' => $datas]);
    // }

    public function scopeSearch($query, $datas) {
        //$datas = array_filter($datas, 'strlen');
        if(empty($datas)) {
            return $query;
        }
        foreach($datas as $k => $v) {
            $query = $query->wherer("input_info[$k]", $v);
        }
        return $query;
    }

}
